

/*rt-thread相关的头文件*/
/*rt-thread相关的*/
#include	"board.h"
#include	"rthw.h"
#include  <rtthread.h>

#define _SCB_BASE       (0xE000E010UL)
#define _SYSTICK_CTRL   (*(rt_uint32_t *)(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD   (*(rt_uint32_t *)(_SCB_BASE + 0x4))
#define _SYSTICK_VAL    (*(rt_uint32_t *)(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB  (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI    (*(rt_uint8_t  *)(0xE000ED23UL))

// Updates the variable SystemCoreClock and must be called 
// whenever the core clock is changed during program execution.
extern void SystemCoreClockUpdate(void);

// Holds the system core clock, which is the system clock 
// frequency supplied to the SysTick timer and the processor 
// core clock.
extern uint32_t SystemCoreClock;

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
    if ((ticks - 1) > 0xFFFFFF)
    {
        return 1;
    }
    
    _SYSTICK_LOAD = ticks - 1; 
    _SYSTICK_PRI = 0xFF;
    _SYSTICK_VAL  = 0;
    _SYSTICK_CTRL = 0x07;  
    
    return 0;
}

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
#define RT_HEAP_SIZE 3072
/*从内部SRAM里面分配一部分静态内存作为rtt的堆空间，这里配置为6KB*/
static uint32_t rt_heap[RT_HEAP_SIZE];	// heap default size: 4K(1024 * 4)
RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}

RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif

/**
 * @brief 开发板硬件初始化函数
 * @param 无
 * @retval 无
 *
 *  @attention
 *		RTT把开发板相关的初始化函数统一放到board.c文件中实现
 *		当然，你想把这些函数统一放到main.c文件也是可以的
 */
void rt_hw_board_init()
{	
	/* System Clock Update */
	SystemCoreClockUpdate();
	
	/* System Tick Configuration */
	_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);   //DS18B20测温度完成后，得调用此函数
	/*硬件BSP初始化统统放在这里*/
    InitAmmeter();
    LED_GPIO_Config();
	ILI9341_Init ();

    EXTI_Config();     //LoRA中断管教
    SpiInit();
    SX1276Init();     //初始化RA2模块
    SX1276Receive();  //上电设为接收状态
    PictureInit();    //一定得在SX1278配置完成之后

    ADCx_Init();
    DS18B20_GPIO_Init();
    Control_GPIO_Config();
    //USART_Config();
    //DAC_Mode_Init();
	cpu_usage_init();
    CRC_Config();
    BASIC_TIM_Init();  //专门定时用的定时器
    //这里还得添加一个专门的DAC(驱动产生4mA~20mA的电流)
    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();     //这个是干嘛的
#endif
    
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
	rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
    
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}

/**
 *	@brief SysTick中断服务函数
 *  @param 无
 *	@retval 无
 *	
 *	@attention 
 *		SysTick中断服务函数在固件库文件stm32f10x_it.c中也定义的，而现在
 *		在board.c中又定义一次，那么在编译的时候会出现重复定义的错误，解决
 *		方法是可以把stm32f10x_it.c中的注释掉或者删除即可.
 */
void SysTick_Handler(void)
{
	/* enter interrupt */
	rt_interrupt_enter();

	rt_tick_increase();

	/* leave interrupt */
	rt_interrupt_leave();
}

/**
 *	@brief 重映射串口DEBUG_USARTx到rt_kprintf()函数
 *		Note：DEBUG_USARTx是在bsp_usart.h中定义的宏，默认使用串口1
 *	@param str:要输出到串口的字符串
 *	@retval 无
 */
void rt_hw_console_output(const char *str)
{
        /*进入临界段*/
    rt_enter_critical();
	
	/*输出字符，直到遇到'\0'*/
	while(*str != '\0')
	{	/*换行->回车换行*/
		if(*str=='\n')
		{
			USART_SendByte(DEBUG_USARTx,'\r');
			while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE)==RESET);
		}
		USART_SendByte(DEBUG_USARTx,*str++);
		while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE)==RESET);
	}
	
        /*退出临界段*/
    rt_exit_critical();
}
